﻿using Pay.Core;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Web;

namespace Pay.Token {
    public class SecuritySignHelper {
        public const string Partner = "partner";
        public const string Sign = "sign";

        public string query_str { get; set; }
        public string form_str { get; set; }

        /// <summary>
        /// 获取防篡改签名，组织原始字符串的方式为：先get后post，该签名要求partner在加密时为全小写，同时该方法隐含要求partner和sign必须通过Headers方式传递  
        /// </summary>
        /// <param name="getCollection">通过QueryString方式传递的键值集合,如果内部包含partner或者sign，相关字段在组织原始字符串时将会被移除</param>  
        /// <param name="partnerKey">合作Key</param>
        /// <param name="postCollection">通过Form方式传递的键值集合，如果包含partner或者sign，此部分不会被做特殊处理</param>  
        /// <returns></returns>  
        public string GetSecuritySign(NameValueCollection getCollection, string partnerKey,
                                             string timespan = "", string nonce = "",
                                             NameValueCollection postCollection = null,
                                             string postData = "") {
            if (string.IsNullOrWhiteSpace(partnerKey)) {
                throw new ArgumentNullException();
            }
            var dic = GetSortedDictionary(getCollection,
                (k) => {
                    //过滤partner及sign  
                    //return string.Equals(k, Partner, StringComparison.OrdinalIgnoreCase) || string.Equals(k, Sign, StringComparison.OrdinalIgnoreCase);
                    return string.Equals(k, Sign, StringComparison.OrdinalIgnoreCase);
                });
            //dic.Add(Partner, partner);
            StringBuilder tmp = new StringBuilder();
            query_str = FillStringBuilder(dic);//将QueryString按字母排序填入StringBuilder
            tmp.Append(query_str);

            dic = GetSortedDictionary(postCollection);
            form_str = FillStringBuilder(dic);//将Form按字母排序填入StringBuilder
            tmp.Append(form_str);

            tmp.Append(postData);//将json字符串填入StringBuilder
            tmp.Append(partnerKey);//在尾部添加key  
            tmp.Append(timespan);//在尾部添加timespan  
            tmp.Append(nonce);//在尾部添加nonce  
            string str = tmp.ToString();
            return SecureHelper.MD5(str);//获取32位长度的Md5摘要  
        }

        private SortedDictionary<string, string> GetSortedDictionary(NameValueCollection collection, Func<string, bool> filter = null) {//获取排序的键值对  
            SortedDictionary<string, string> dic = new SortedDictionary<string, string>();
            if (collection != null && collection.Count > 0) {
                foreach (var k in collection.AllKeys) {
                    if (filter == null || !filter(k)) {//如果没设置过滤条件或者无需过滤  
                        dic.Add(k, collection[k]);
                    }
                }
            }
            return dic;
        }

        private string FillStringBuilder(SortedDictionary<string, string> dic) {
            string str = string.Empty;
            foreach (var kv in dic)
                str += "&" + kv.Key + "=" + kv.Value;
            str = str.Trim('&');
            return str;
        }

        private void RefEncoding(ref Encoding encoding) {
            if (encoding == null) {
                encoding = Encoding.Default;
            }
        }

        public string GetString(NameValueCollection collection) {
            return FillStringBuilder(GetSortedDictionary(collection));
        }
    }
}